package widget.list;

import android.content.Context;
import android.graphics.Color;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;


/**
 * Created by Mr.Fan on 2016-6-7.
 */
public class ListView extends RecyclerView {
    private View emptyView;
    private ArrayList<View> mHeaderViews = new ArrayList<>();
    private ArrayList<View> mFootViews = new ArrayList<>();
    private RecyclerViewBorder border = null;
    private RecycleViewDivider divider = null;

    public ListView(Context context) {
        super(context);
        init();
    }

    public ListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        setLayoutManager(new LinearLayoutManager(getContext()));
        setItemAnimator(new DefaultItemAnimator());
        setHasFixedSize(false);
        setOverScrollMode(OVER_SCROLL_NEVER);
    }

    public RecyclerViewBorder setBorder(int v) {
        return setBorder(v, 0);
    }

    public RecyclerViewBorder setBorder(int v, int h) {
        if (border != null)
            removeItemDecoration(border);
        border = new RecyclerViewBorder(v, h);
        addItemDecoration(border);
        return border;
    }

    public RecycleViewDivider setItemDecoration(int space) {
        return setItemDecoration(space, Color.TRANSPARENT);
    }

    public RecycleViewDivider setItemDecoration(int space, int color) {
        if (divider != null)
            removeItemDecoration(divider);
        divider = new RecycleViewDivider(getContext(), LinearLayoutManager.HORIZONTAL, space, color);
        addItemDecoration(divider);
        return divider;
    }

    public void addHeaderView(View view) {
        mHeaderViews.add(view);
    }

    public void addFootView(View view) {
        mFootViews.add(view);
    }

    @Override
    public void setAdapter(Adapter adapter) {
        if (!mHeaderViews.isEmpty() || !mFootViews.isEmpty()) {
            adapter.registerAdapterDataObserver(childObserver);
            adapter = new ListViewAdapter(mHeaderViews, mFootViews, adapter);
        }
        adapter.registerAdapterDataObserver(emptyObserver);
        super.setAdapter(adapter);
        emptyObserver.onChanged();
    }

    public void setEmptyView(View view) {
        this.emptyView = view;
        if (getAdapter() != null) {
            getAdapter().notifyDataSetChanged();
        }
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);
        }
    }


    private AdapterDataObserver emptyObserver = new AdapterDataObserver() {
        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            checkEmpty();
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            checkEmpty();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            checkEmpty();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            checkEmpty();
        }

        @Override
        public void onChanged() {
            checkEmpty();
        }

        private void checkEmpty() {
            Adapter<?> adapter = getAdapter();
            if (emptyView != null)
                if (adapter == null || (adapter.getItemCount() - mHeaderViews.size() - mFootViews.size()) == 0) {
                    emptyView.setVisibility(View.VISIBLE);
                    setVisibility(View.GONE);
                } else {
                    emptyView.setVisibility(View.GONE);
                    setVisibility(View.VISIBLE);
                }
        }
    };

    private AdapterDataObserver childObserver = new AdapterDataObserver() {
        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            Adapter<?> adapter = getAdapter();
            if (adapter != null) {
                adapter.notifyItemRangeChanged(mHeaderViews.size() + positionStart, itemCount);
            }
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            Adapter<?> adapter = getAdapter();
            if (adapter != null) {
                adapter.notifyItemMoved(mHeaderViews.size() + fromPosition, itemCount);
            }
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            Adapter<?> adapter = getAdapter();
            if (adapter != null) {
                adapter.notifyItemRangeRemoved(mHeaderViews.size() + positionStart, itemCount);
            }
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            Adapter<?> adapter = getAdapter();
            if (adapter != null) {
                adapter.notifyItemRangeInserted(mHeaderViews.size() + positionStart, itemCount);
            }
        }

        @Override
        public void onChanged() {
            Adapter<?> adapter = getAdapter();
            if (adapter != null) {
                adapter.notifyDataSetChanged();
            }
        }

    };

    @Override
    public void scrollToPosition(int position) {
        super.scrollToPosition(fixedPosition(position));
    }

    @Override
    public void smoothScrollToPosition(int position) {
        super.smoothScrollToPosition(fixedPosition(position));
    }

    private int fixedPosition(int position) {
        if (position <= 0)
            position = 0;
        else if (position >= getAdapter().getItemCount())
            position = getAdapter().getItemCount() - 1;
        return position;
    }

}
